package com.cskaoyan.service.wx.impl;

import com.alibaba.druid.util.StringUtils;
import com.cskaoyan.bean.pojo.*;
import com.cskaoyan.bean.wx.cart.*;
import com.cskaoyan.mapper.*;
import com.cskaoyan.service.wx.WxCartService;
import com.cskaoyan.util.CurrentUserUtils;
import lombok.SneakyThrows;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.System;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Classname WxCartService
 * @Description
 * @Date 2021/8/14 14:56
 * @Created by songweinan
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class WxCartServiceImpl implements WxCartService {

    @Autowired
    CartMapper cartMapper;

    @Autowired
    AddressMapper addressMapper;

    @Autowired
    SystemMapper systemMapper;

    @Autowired
    CouponMapper couponMapper;

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    CouponUserMapper couponUserMapper;

    @Autowired
    UserMapper userMapper;

    /**
     * 获取购物车首页信息
     *
     * @return
     */
    @Override
    public IndexVo getCartIndex() {

        Integer userId = getCurrentUserId();

        //先查询 * goodsCount : 3
        //         * checkedGoodsCount : 1
        //         * goodsAmount : 497
        //         * checkedGoodsAmount : 99
        CartExample cartExample = new CartExample();
        CartExample.Criteria criteria = cartExample.createCriteria();
        if (userId != null) {
            criteria.andUserIdEqualTo(userId);
        }
        criteria.andDeletedEqualTo(false);

        Integer goodsCount = 0;
        Integer checkedGoodsCount = 0;
        BigDecimal goodsAmount = new BigDecimal(0);
        BigDecimal checkedGoodsAmount = new BigDecimal(0);
        List<Cart> cartList = cartMapper.selectByExample(cartExample);
        ArrayList<CartListBean> cartListBeans = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (Cart cart : cartList) {
            //计算出四个参数进行封装
            goodsCount += cart.getNumber();
            goodsAmount = goodsAmount.add(cart.getPrice().multiply(BigDecimal.valueOf(cart.getNumber())));
            if (cart.getChecked()) {
                checkedGoodsCount += cart.getNumber();
                checkedGoodsAmount = checkedGoodsAmount.add(cart.getPrice().multiply(BigDecimal.valueOf(cart.getNumber())));
            }

            CartListBean cartListBean = new CartListBean(cart.getId(), cart.getUserId(), cart.getGoodsId(), cart.getGoodsSn(), cart.getGoodsName(), cart.getProductId(), cart.getPrice(),
                    (int) cart.getNumber(), cart.getChecked(), cart.getPicUrl(), sdf.format(cart.getAddTime()), sdf.format(cart.getUpdateTime()), cart.getDeleted(), cart.getSpecifications());
            cartListBeans.add(cartListBean);
        }

        CartTotalBean cartTotalBean = new CartTotalBean(goodsCount, checkedGoodsCount, goodsAmount, checkedGoodsAmount);

        IndexVo indexVo = new IndexVo(cartTotalBean, cartListBeans);
        return indexVo;
    }

    /**
     * 购物车勾选、全选与反勾选
     *
     * @param checkedBo
     * @return
     */
    @Override
    public IndexVo getCartIndexChanged(CheckedBo checkedBo) {

        Integer userId = getCurrentUserId();

        //判断全选的逻辑 =>遍历
        Integer[] productIds = checkedBo.getProductIds();
        for (Integer productId : productIds) {
            //先更改对应productId 对应的checked值
            //TODO 可以用foreach循环优化
            int affectedRows = cartMapper.updateIsCheckByProductId(productId, checkedBo.getIsChecked());
        }

        //查询信息并做封装
        CartExample cartExample = new CartExample();
        CartExample.Criteria criteria = cartExample.createCriteria();
        if (userId != null) {
            criteria.andUserIdEqualTo(userId);
        }
        criteria.andDeletedEqualTo(false);

        Integer goodsCount = 0;
        Integer checkedGoodsCount = 0;
        BigDecimal goodsAmount = new BigDecimal(0);
        BigDecimal checkedGoodsAmount = new BigDecimal(0);
        List<Cart> cartList = cartMapper.selectByExample(cartExample);
        ArrayList<CartListBean> cartListBeans = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (Cart cart : cartList) {
            //计算出四个参数进行封装
            goodsCount += cart.getNumber();
            goodsAmount = goodsAmount.add(cart.getPrice().multiply(BigDecimal.valueOf(cart.getNumber())));
            if (cart.getChecked()) {
                checkedGoodsCount += cart.getNumber();
                checkedGoodsAmount = checkedGoodsAmount.add(cart.getPrice().multiply(BigDecimal.valueOf(cart.getNumber())));
            }

            CartListBean cartListBean = new CartListBean(cart.getId(), cart.getUserId(), cart.getGoodsId(), cart.getGoodsSn(), cart.getGoodsName(), cart.getProductId(), cart.getPrice(),
                    (int) cart.getNumber(), cart.getChecked(), cart.getPicUrl(), sdf.format(cart.getAddTime()), sdf.format(cart.getUpdateTime()), cart.getDeleted(), cart.getSpecifications());
            cartListBeans.add(cartListBean);
        }

        CartTotalBean cartTotalBean = new CartTotalBean(goodsCount, checkedGoodsCount, goodsAmount, checkedGoodsAmount);

        IndexVo indexVo = new IndexVo(cartTotalBean, cartListBeans);

        return indexVo;
    }

    /**
     * 将当前商品加入购物车
     *
     * @param addCartBo
     * @return
     */
    @SneakyThrows
    @Override
    public Integer addCart(AddCartBo addCartBo) {

        Integer userId = getCurrentUserId();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date addTime = sdf.parse(sdf.format(new Date()));

        //首先查询该用户是不是已经有该商品了
        CartExample cartExample = new CartExample();
        CartExample.Criteria criteria = cartExample.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andGoodsIdEqualTo(addCartBo.getGoodsId());
        criteria.andProductIdEqualTo(addCartBo.getProductId());
        criteria.andDeletedEqualTo(false);

        List<Cart> carts = cartMapper.selectByExample(cartExample);
        if(carts.size() > 0 ){
            //说明购物车已经有该商品  就修改数量
            Cart cart1 = carts.get(0);
            Cart cart = new Cart();
            cart.setId(cart1.getId());
            cart.setNumber((short)(cart1.getNumber()+addCartBo.getNumber()));
            int i = cartMapper.updateByPrimaryKeySelective(cart);
        }else{
            //先查询出插入所需要的其他信息
            Cart cart = cartMapper.selectCartInfo(addCartBo.getGoodsId());
            cart.setId(null);
            cart.setUserId(userId);
            cart.setProductId(addCartBo.getProductId());
            cart.setNumber(addCartBo.getNumber());
            cart.setChecked(true);
            cart.setAddTime(addTime);
            cart.setUpdateTime(addTime);
            cart.setDeleted(false);

            int affectedRows = cartMapper.insert(cart);
        }


        Integer cartTotalNumber = cartMapper.selectCartTotalNumberByUserId(userId);
        return cartTotalNumber;
    }

    /**
     * 查询某用户当前购物车中货品的总数量(包括checked和unchecked)
     *
     * @return
     */
    @Override
    public Integer getGoodsCount() {

        Integer userId = getCurrentUserId();

        Integer cartTotalNumber = cartMapper.selectCartTotalNumberByUserId(userId);
        return cartTotalNumber;
    }

    /**
     * 修改购物车商品数量
     * @param updateCartBo
     * @return
     */
    @Override
    public Integer updateCart(UpdateCartBo updateCartBo) {

        Integer userId = getCurrentUserId();

        Cart cart = new Cart();
        cart.setId(updateCartBo.getId());
        cart.setNumber(updateCartBo.getNumber());
        int affectedRows = cartMapper.updateByPrimaryKeySelective(cart);
        return 200;
    }

    /**
     * 删除购物车中的部分商品
     * @param deleteCartsBo
     * @return
     */
    @Override
    public IndexVo deleteCarts(DeleteCartsBo deleteCartsBo) {

        Integer userId = getCurrentUserId();

        //先删除productIds和userId对应的cart信息
        Integer[] productIds = deleteCartsBo.getProductIds();
        for (Integer productId : productIds) {
            //TODO 可用foreach标签优化
            int affectedRows = cartMapper.deleteCartByUserIdAndProductId(userId, productId);
        }

        //获取最新的购物车信息并封装返回
        //查询信息并做封装
        CartExample cartExample = new CartExample();
        CartExample.Criteria criteria = cartExample.createCriteria();
        if (userId != null) {
            criteria.andUserIdEqualTo(userId);
        }
        criteria.andDeletedEqualTo(false);

        Integer goodsCount = 0;
        Integer checkedGoodsCount = 0;
        BigDecimal goodsAmount = new BigDecimal(0);
        BigDecimal checkedGoodsAmount = new BigDecimal(0);
        List<Cart> cartList = cartMapper.selectByExample(cartExample);
        ArrayList<CartListBean> cartListBeans = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (Cart cart : cartList) {
            //计算出四个参数进行封装
            goodsCount += cart.getNumber();
            goodsAmount = goodsAmount.add(cart.getPrice().multiply(BigDecimal.valueOf(cart.getNumber())));
            if (cart.getChecked()) {
                checkedGoodsCount += cart.getNumber();
                checkedGoodsAmount = checkedGoodsAmount.add(cart.getPrice().multiply(BigDecimal.valueOf(cart.getNumber())));
            }

            CartListBean cartListBean = new CartListBean(cart.getId(), cart.getUserId(), cart.getGoodsId(), cart.getGoodsSn(), cart.getGoodsName(), cart.getProductId(), cart.getPrice(),
                    (int) cart.getNumber(), cart.getChecked(), cart.getPicUrl(), sdf.format(cart.getAddTime()), sdf.format(cart.getUpdateTime()), cart.getDeleted(), cart.getSpecifications());
            cartListBeans.add(cartListBean);
        }

        CartTotalBean cartTotalBean = new CartTotalBean(goodsCount, checkedGoodsCount, goodsAmount, checkedGoodsAmount);

        IndexVo indexVo = new IndexVo(cartTotalBean, cartListBeans);

        return indexVo;
    }

    /**
     * 添加订单信息
     * 获取返回值  添加订单  修改system表中未支付订单数量
     * @param cartId
     * @param addressId
     * @param couponId
     * @param grouponRulesId
     * @return
     */
    @SneakyThrows
    @Override
    public CheckOutVo addOrder(Integer cartId, Integer addressId, Integer couponId, Integer grouponRulesId) {

        Integer userId = getCurrentUserId();

        CheckOutVo checkOutVo = new CheckOutVo();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        //先查出地址信息
        Address address = null;
        if(addressId != 0){
            AddressExample addressExample = new AddressExample();
            AddressExample.Criteria criteria = addressExample.createCriteria();
            criteria.andIdEqualTo(addressId);
            criteria.andDeletedEqualTo(false);
            List<Address> addresses = addressMapper.selectByExample(addressExample);
            address = addresses.get(0);
        }

        if(address == null){
            //没传addressId则用默认的
            AddressExample addressExample = new AddressExample();
            AddressExample.Criteria criteria = addressExample.createCriteria();
            criteria.andUserIdEqualTo(userId);
            criteria.andIsDefaultEqualTo(true);
            criteria.andDeletedEqualTo(false);
            List<Address> addresses = addressMapper.selectByExample(addressExample);
            address = addresses.get(0);
        }

        CheckedAddressBean checkedAddressBean = new CheckedAddressBean(address.getId(), address.getName(), address.getUserId(), address.getProvinceId(), address.getCityId(), address.getAreaId(), address.getAddress(), address.getMobile(),
                address.getIsDefault(), sdf.format(address.getAddTime()), sdf.format(address.getUpdateTime()), address.getDeleted());

        //再查出goodsTotalPrice
        BigDecimal checkedGoodsTotalPrice = new BigDecimal(0);
        int checkedGoodTypeNumber = 0;
        ArrayList<CartListBean> checkedGoodsList = new ArrayList<>();
        if(cartId != 0){
            //fastAdd的商品
            CartExample cartExample = new CartExample();
            CartExample.Criteria criteria = cartExample.createCriteria();
            criteria.andIdEqualTo(cartId);
            criteria.andDeletedEqualTo(false);
            List<Cart> carts = cartMapper.selectByExample(cartExample);
            Cart cart = carts.get(0);
            checkedGoodTypeNumber = 1;
            checkedGoodsTotalPrice = checkedGoodsTotalPrice.add(cart.getPrice().multiply(BigDecimal.valueOf(cart.getNumber())));
            CartListBean cartListBean = new CartListBean(cart.getId(), cart.getUserId(), cart.getGoodsId(), cart.getGoodsSn(), cart.getGoodsName(), cart.getProductId(), cart.getPrice(),
                    (int) cart.getNumber(), cart.getChecked(), cart.getPicUrl(), sdf.format(cart.getAddTime()), sdf.format(cart.getUpdateTime()), cart.getDeleted(), cart.getSpecifications());
            checkedGoodsList.add(cartListBean);

        }else{
            //cartId == 0  √
            CartExample cartExample = new CartExample();
            CartExample.Criteria criteria = cartExample.createCriteria();
            if (userId != null) {
                criteria.andUserIdEqualTo(userId);
            }
            criteria.andDeletedEqualTo(false);
            criteria.andCheckedEqualTo(true);

            List<Cart> cartList = cartMapper.selectByExample(cartExample);
            for (Cart cart : cartList) {
                checkedGoodsTotalPrice = checkedGoodsTotalPrice.add(cart.getPrice().multiply(BigDecimal.valueOf(cart.getNumber())));
                checkedGoodTypeNumber +=  1;
                CartListBean cartListBean = new CartListBean(cart.getId(), cart.getUserId(), cart.getGoodsId(), cart.getGoodsSn(), cart.getGoodsName(), cart.getProductId(), cart.getPrice(),
                        (int) cart.getNumber(), cart.getChecked(), cart.getPicUrl(), sdf.format(cart.getAddTime()), sdf.format(cart.getUpdateTime()), cart.getDeleted(), cart.getSpecifications());
                checkedGoodsList.add(cartListBean);
            }
        }

        //根据system表查出包邮额度及运费等信息
        List<Map<String, String>> systemMap = systemMapper.selectKeyAndValue();
        BigDecimal expressFreightMin = new BigDecimal(0);
        BigDecimal expressFreightValue = new BigDecimal(0);
        Integer orderUnpaidNumber = 0;

        for (Map<String, String> stringStringMap : systemMap) {

            if ("cskaoyan_mall_order_unpaid".equals(stringStringMap.get("key_name"))) {
                orderUnpaidNumber = Integer.parseInt(stringStringMap.get("key_value"));
            }
            if ("cskaoyan_mall_express_freight_min".equals(stringStringMap.get("key_name"))) {
                expressFreightMin = BigDecimal.valueOf(Double.parseDouble(stringStringMap.get("key_value")));
            }
            if ("cskaoyan_mall_express_freight_value".equals(stringStringMap.get("key_name"))) {
                expressFreightValue = BigDecimal.valueOf(Double.parseDouble(stringStringMap.get("key_value")));
            }
        }

        //如果商品总价超过免运费额度 则 运费为0  反之为运费为value
        if(checkedGoodsTotalPrice.compareTo(expressFreightMin) > 0){
            checkOutVo.setFreightPrice(new BigDecimal(0));
        }else{
            checkOutVo.setFreightPrice(expressFreightValue);
        }

        //优惠券数量
        //查询该用户所拥有的优惠券数量
        CouponUserExample couponUserExample = new CouponUserExample();
        CouponUserExample.Criteria criteria = couponUserExample.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andStartTimeLessThanOrEqualTo(new Date());
        criteria.andEndTimeGreaterThanOrEqualTo(new Date());
        criteria.andDeletedEqualTo(false);
        List<CouponUser> couponUsers = couponUserMapper.selectByExample(couponUserExample);

        //查询这些优惠券中额度可用的优惠券
        ArrayList<Coupon> couponsAvailable = new ArrayList<>();
        for (CouponUser couponUser : couponUsers) {
            CouponExample couponExample = new CouponExample();
            CouponExample.Criteria criteria1 = couponExample.createCriteria();
            criteria1.andIdEqualTo(couponUser.getCouponId());
            criteria1.andMinLessThanOrEqualTo(checkedGoodsTotalPrice);
            criteria1.andDeletedEqualTo(false);
            List<Coupon> coupons = couponMapper.selectByExample(couponExample);
            if(coupons.size() > 0){
                couponsAvailable.addAll(coupons);
            }
        }

        //优惠券面值
        //如果传入couponId则查询出其信息
        Coupon coupon = null;
        if(couponId != 0){
            CouponExample couponExample = new CouponExample();
            CouponExample.Criteria criteria1 = couponExample.createCriteria();
            criteria1.andIdEqualTo(couponId);
            criteria1.andDeletedEqualTo(false);
            //criteria1.andMinLessThanOrEqualTo(checkedGoodsTotalPrice);
            //criteria1.andStartTimeLessThanOrEqualTo(new Date());
            //criteria1.andEndTimeGreaterThanOrEqualTo(new Date());
            List<Coupon> coupons = couponMapper.selectByExample(couponExample);
            if(coupons.size() > 0){
                coupon = coupons.get(0);
            }
        }

//        //如果没传入但有可用优惠券 就选择一张优惠面额最大的使用
//        if(coupon == null && couponsAvailable.size() > 0){
//            BigDecimal maxCouponAmount = new BigDecimal(0);
//            for (Coupon coupon1 : couponsAvailable) {
//                if(coupon1.getDiscount().compareTo(maxCouponAmount) > 0){
//                    maxCouponAmount = coupon1.getDiscount();
//                    coupon = coupon1;
//                }
//            }
//        }

        //给vo的CouponId CouponPrice  AvailableCouponLength 赋值
        if(coupon == null){
            checkOutVo.setCouponId(0);
            checkOutVo.setCouponPrice(new BigDecimal(0));
        }else{
            checkOutVo.setCouponId(coupon.getId());
            checkOutVo.setCouponPrice(coupon.getDiscount());
        }
        checkOutVo.setAvailableCouponLength(couponsAvailable.size());

        //integral_price 定为0
        BigDecimal integralPrice = new BigDecimal(0);
        checkOutVo.setGrouponPrice(new BigDecimal(0));//团购优惠价 0
        checkOutVo.setGrouponRulesId(grouponRulesId);
        checkOutVo.setCheckedAddress(checkedAddressBean);
        checkOutVo.setOrderTotalPrice(checkedGoodsTotalPrice.add(checkOutVo.getFreightPrice()).subtract(checkOutVo.getCouponPrice()));
        checkOutVo.setActualPrice(checkOutVo.getOrderTotalPrice().subtract(integralPrice));
        checkOutVo.setCheckedGoodsList(checkedGoodsList);
        checkOutVo.setGoodsTotalPrice(checkedGoodsTotalPrice);
        checkOutVo.setCouponId(couponId);
        checkOutVo.setAddressId(addressId);

        //找出购物车选中的所有商品  cartId == 0  cartId != 0
        //插入订单表  插入order_goods表
        //再修改system表中的cskaoyan_mall_order_unpaid对应的value值
        //最后修改couponId对应的couponUser的字段  如useTime  TODO

//        String orderSn = String.valueOf(System.currentTimeMillis());
//
//        Date addTime = sdf.parse(sdf.format(new Date()));
//        //插入订单信息
//        Order order = new Order();
//        order.setId(null);
//        order.setUserId(userId);
//        //用当前时间戳当订单编号
//        order.setOrderSn(orderSn);
//        order.setOrderStatus((short)101);//未付款
//        order.setConsignee(address.getName());
//        order.setMobile(address.getMobile());
//        order.setAddress(address.getAddress());
//        order.setGoodsPrice(checkedGoodsTotalPrice);
//        order.setFreightPrice(checkOutVo.getFreightPrice());
//        order.setCouponPrice(checkOutVo.getCouponPrice());
//        order.setIntegralPrice(integralPrice);
//        order.setGrouponPrice(checkOutVo.getGrouponPrice());
//        order.setOrderPrice(checkOutVo.getOrderTotalPrice());
//        order.setActualPrice(checkOutVo.getActualPrice());
//        order.setComments((short)checkedGoodTypeNumber);
//        order.setAddTime(addTime);
//        order.setUpdateTime(addTime);
//        order.setDeleted(false);
//        int affectedRows = orderMapper.insertSelective(order);
//
//        //再修改system表中的cskaoyan_mall_order_unpaid对应的value值
//        //最后修改couponId对应的couponUser的字段  如useTime  TODO
//        int affectedRows2 = systemMapper.updateUnpaidValue(orderUnpaidNumber + 1);

        return checkOutVo;
    }

    /**
     * 商品页面的立即购买
     *  加入购物车
     *  最终是要插入一条cart数据并返回自增的cartId
     * @param addCartBo
     * @return
     */
    @SneakyThrows
    @Override
    public Integer fastadd(AddCartBo addCartBo) {

        Integer userId = getCurrentUserId();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date addTime = sdf.parse(sdf.format(new Date()));

        //连接查询出插入所需要的其他信息
        Cart cart = cartMapper.selectCartInfo(addCartBo.getGoodsId());
        cart.setId(null);
        cart.setUserId(userId);
        cart.setProductId(addCartBo.getProductId());
        cart.setNumber(addCartBo.getNumber());
        cart.setChecked(true);
        cart.setAddTime(addTime);
        cart.setUpdateTime(addTime);
        cart.setDeleted(false);

        int affectedRows = cartMapper.insert(cart);
        Integer cartId = cart.getId();
        return cartId;
    }

    /**
     * 返回当前用户的用户id
     * @return
     */
    private Integer getCurrentUserId() {

        String username = (String) SecurityUtils.getSubject().getPrincipal();
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        if(!StringUtils.isEmpty(username)){
            criteria.andUsernameEqualTo(username);
        }
        criteria.andDeletedEqualTo(false);
        List<User> users = userMapper.selectByExample(userExample);
        return users.get(0).getId();
}
}
